#include "Stdafx.h"

#include "Log.h"


struct LogRecord
{
public:
	int m_iLogId;
	FILE* m_FP;
	LogRecord* m_pNext;
};

LogRecord* pLogRecordChain = NULL;

void AddLogRecord(LogRecord* rec)
{
	if(pLogRecordChain ==  NULL)
	{
		pLogRecordChain = rec;
		rec->m_pNext = NULL;
	}
	else
	{
		LogRecord* last = pLogRecordChain;
		while(last->m_pNext != NULL)
			last = last->m_pNext;
		last->m_pNext = rec;
		rec->m_pNext = NULL;
	}
}

LogRecord* FindLogRecord(int iLogId)
{
	LogRecord* rec = pLogRecordChain;
	while(rec != NULL)
	{
		if(rec->m_iLogId == iLogId)
			return rec;
		rec = rec->m_pNext;
	} // while

	return NULL;
}

int GetNewLogRecordId()
{
	int max = 0;

	LogRecord* rec = pLogRecordChain;
	while(rec != NULL)
	{
		if(rec->m_iLogId > max)
			max = rec->m_iLogId;
		rec = rec->m_pNext;
	} // while

	return max + 1;
}

void RemoveLogRecord(LogRecord* rec)
{
	// find previous
	LogRecord* prev = NULL;
	if(rec != pLogRecordChain)
	{
		prev = pLogRecordChain;
		while(prev->m_pNext != rec)
			prev = prev->m_pNext;
	}

	if(prev == NULL)
	{
		pLogRecordChain = rec->m_pNext;
	}
	else
	{
		prev->m_pNext = rec->m_pNext;
	}
}

int LogInit(char* szFilename)
{
	FILE* fp = NULL;
	errno_t err = fopen_s(&fp, szFilename, "w");
	if(fp)
	{
		LogRecord* rec = new LogRecord();
		rec->m_iLogId = GetNewLogRecordId();
		rec->m_FP = fp;
		rec->m_pNext = NULL;

		AddLogRecord(rec);
		return rec->m_iLogId;
	}
	else
	{
		//assert(false);
		return -1;
	}
}

char sMsg[2000];
	
void _cdecl LogMessage(int iLogId, const char* message)
{
	LogRecord* rec = FindLogRecord(iLogId);
	if(rec != NULL)
	{

		fprintf(rec->m_FP, message);
		fflush(rec->m_FP);
	}
}



void _cdecl LogMessage(int logId, const wchar_t* message)
{
	LogRecord* rec = FindLogRecord(logId);
	if(rec != NULL)
	{
		fwprintf(rec->m_FP, message);
		fflush(rec->m_FP);
	}
}

void _cdecl LogMessageFP(FILE* fp, const char* message)
{
	fprintf(fp, message);
	fflush(fp);
}


void LogClose(int iLogId)
{
	LogRecord* rec = FindLogRecord(iLogId);
	if(rec != NULL)
	{
		fclose(rec->m_FP);
		RemoveLogRecord(rec);
		delete rec;
	}
}

void LogBB(int logId, BitBoard bb)
{
	bool bPrintBefore = true;
	for(int i = 31; i >= 0; i-=4)
	{
		for(int j = i - 3; j <= i; j++)
		{
			if(bPrintBefore)
				LogMessage(logId, ".");

			// choose figure
			int wm = bb.wm & (1 << j);
			int wk = bb.wk & (1 << j);
			int bm = bb.bm & (1 << j);
			int bk = bb.bk & (1 << j);

			if(wm)
				LogMessage(logId, "w");
			else if(wk)
				LogMessage(logId, "W");
			else if(bm)
				LogMessage(logId, "b");
			else if(bk)
				LogMessage(logId, "B");
			else
				LogMessage(logId, "0");

			if(! bPrintBefore)
				LogMessage(logId, ".");
		}

		LogMessage(logId, "\n");
		bPrintBefore =  !bPrintBefore;
	}

	LogMessage(logId, "\n");
}

void LogBB_FP(FILE* fp, BitBoard bb)
{
	bool bPrintBefore = true;
	for(int i = 31; i >= 0; i-=4)
	{
		for(int j = i - 3; j <= i; j++)
		{
			if(bPrintBefore)
				LogMessageFP(fp, ".");

			// choose figure
			int wm = bb.wm & (1 << j);
			int wk = bb.wk & (1 << j);
			int bm = bb.bm & (1 << j);
			int bk = bb.bk & (1 << j);

			if(wm)
				LogMessageFP(fp, "w");
			else if(wk)
				LogMessageFP(fp, "W");
			else if(bm)
				LogMessageFP(fp, "b");
			else if(bk)
				LogMessageFP(fp, "B");
			else
				LogMessageFP(fp, "0");

			if(! bPrintBefore)
				LogMessageFP(fp, ".");
		}

		LogMessageFP(fp, "\n");
		bPrintBefore =  !bPrintBefore;
	}

	LogMessageFP(fp, "\n");
}



void LogBB64(int logId, BitBoard64 bb)
{
	bool bPrintBefore = true;
	for(int i = 49; i >= 0; i-=5)
	{
		for(int j = i - 4; j <= i; j++)
		{
			if(bPrintBefore)
				LogMessage(logId, ".");

			// choose figure
			uint64 wm = bb.wm & (1ull << j);
			uint64 wk = bb.wk & (1ull << j);
			uint64 bm = bb.bm & (1ull << j);
			uint64 bk = bb.bk & (1ull << j);

			if(wm)
				LogMessage(logId, "w");
			else if(wk)
				LogMessage(logId, "W");
			else if(bm)
				LogMessage(logId, "b");
			else if(bk)
				LogMessage(logId, "B");
			else
				LogMessage(logId, "0");

			if(! bPrintBefore)
				LogMessage(logId, ".");
		}

		LogMessage(logId, "\n");
		bPrintBefore =  !bPrintBefore;
	}

	LogMessage(logId, "\n");
}


